package ln.fxspringarchetype.controller.course;

import javafx.beans.binding.Bindings;
import javafx.beans.property.*;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import ln.fxspringarchetype.controller.BaseFxController;
import ln.fxspringarchetype.dialog.course.AddCourseDialog;
import ln.fxspringarchetype.dialog.course.DeleteCourseDialog;
import ln.fxspringarchetype.dialog.course.EditCourseDialog;
import ln.fxspringarchetype.mapper.CourseMapper;
import ln.fxspringarchetype.model.Course;
import org.apache.logging.log4j.util.Strings;
import org.controlsfx.control.Notifications;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

import java.util.Objects;
import java.util.Optional;

@Controller
public class CourseController extends BaseFxController {
    private final IntegerProperty pageNum = new SimpleIntegerProperty(Integer.MIN_VALUE);
    private final IntegerProperty pageSize = new SimpleIntegerProperty(Integer.MIN_VALUE);
    private final IntegerProperty pageCount = new SimpleIntegerProperty(Integer.MIN_VALUE);
    private final StringProperty keyword = new SimpleStringProperty(Strings.EMPTY);

    private final ObjectProperty<ObservableList<Course>> courseRecords = new SimpleObjectProperty<>();

    @FXML
    private TextField searchBox;
    @FXML
    private ChoiceBox<Integer> pageSizeChoice;
    @FXML
    private TableColumn<Course, Integer> idColumn;
    @FXML
    private TableColumn<Course, String> nameColumn;
    @FXML
    private TableColumn<Course, Double> creditColumn;
    @FXML
    private TableColumn<Course, String> descriptionColumn;
    @FXML
    private Pagination pagination;
    @FXML
    private TableView<Course> courseTable;

    @Autowired
    private CourseMapper courseMapper;

    @Override
    public void setCellValueFactories() {
        idColumn.setCellValueFactory(new PropertyValueFactory<>("id"));
        nameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
        descriptionColumn.setCellValueFactory(new PropertyValueFactory<>("description"));
        creditColumn.setCellValueFactory(new PropertyValueFactory<>("credit"));
    }

    @Override
    public void setCellFactories() {

    }

    @Override
    public void createBindings() {
        pageNum.bind(pagination.currentPageIndexProperty());
        pageSize.bind(pageSizeChoice.valueProperty());
        keyword.bind(searchBox.textProperty());
        courseRecords.bind(
                Bindings.createObjectBinding(
                        () -> {
                            int pNum = pageNum.getValue();
                            int pSize = pageSize.getValue();
                            String kw = keyword.getValue();
                            if (pNum < 0 || pSize <= 0) {
                                return FXCollections.emptyObservableList();
                            }
                            if (Strings.isEmpty(kw)) {
                                return FXCollections.observableList(courseMapper.findPage(pNum, pSize));
                            } else {
                                return FXCollections.observableList(courseMapper.findPageByName(kw, pNum, pSize));
                            }
                        }, pageNum, pageSize, keyword));
        courseTable.itemsProperty().bind(courseRecords);
        //根据页码、记录数、查询关键词自动计算结果页数
        pageCount.bind(Bindings.createIntegerBinding(
                () -> {
                    int pNum = pageNum.getValue();
                    int pSize = pageSize.getValue();
                    String kw = keyword.getValue();
                    if (pNum < 0 || pSize <= 0) {
                        return 0;
                    }
                    if (Strings.isEmpty(kw)) {
                        return courseMapper.pageCount(pSize);
                    } else {
                        return courseMapper.pageCountByName(kw, pSize);
                    }
                }, pageNum, pageSize, keyword));
        pagination.pageCountProperty().bind(pageCount);
    }

    @Override
    public void initLayout() {

    }

    @Override
    public void loadData() {
        pagination.setCurrentPageIndex(0);
        pageSizeChoice.getSelectionModel().selectFirst();
    }

    private void reload() {
        pagination.setCurrentPageIndex(-1);
    }

    @FXML
    private void addCourse(ActionEvent actionEvent) {
        AddCourseDialog addCourseDialog = new AddCourseDialog();
        Optional<Course> courseToInsert = addCourseDialog.showAndWait();
        if (courseToInsert.isPresent()) {
            int inserted = courseMapper.insert(courseToInsert.get());
            Notifications notifications;
            if (inserted > 0) {
                notifications = showPrompt("新增课程信息成功",
                        String.format("课程 %s 的信息已经成功添加。", courseToInsert.get().getName()));
                notifications.showInformation();
            } else {
                notifications = showPrompt("新增课程信息失败",
                        String.format("课程 %s 的信息未能成功添加。", courseToInsert.get().getName()));
                notifications.showError();
            }
            reload();
        }
    }

    @FXML
    private void deleteCourse(ActionEvent actionEvent) {
        Course course = courseTable.getSelectionModel().getSelectedItem();
        if (Objects.isNull(course)) {
            //判断是否为空
            showPrompt("没有选择课程信息", "请选择一条课程信息！");
            return;
        }
        DeleteCourseDialog deleteCourseDialog = new DeleteCourseDialog();
        deleteCourseDialog.loadCourse(course);
        Optional<Course> courseToDelete = deleteCourseDialog.showAndWait();
        if (courseToDelete.isPresent()) {
            int deleted = courseMapper.delete(course.getId());
            Notifications notifications;
            if (deleted > 0) {
                notifications = showPrompt("删除课程信息成功",
                        String.format("课程 %s 的信息已经成功删除。", course.getName()));
                notifications.showInformation();
            } else {
                notifications = showPrompt("删除课程信息失败",
                        String.format("课程 %s 的信息没有成功删除。", course.getName()));
                notifications.showError();
            }
            reload();
        }
    }

    @FXML
    private void editCourse(ActionEvent actionEvent) {
        Course course = courseTable.getSelectionModel().getSelectedItem();
        if (Objects.isNull(course)) {
            //判断是否为空
            showPrompt("没有选择课程信息", "请选择一条课程信息！");
            return;
        }
        EditCourseDialog editCourseDialog = new EditCourseDialog();
        editCourseDialog.loadCourse(course);
        Optional<Course> courseToEdit = editCourseDialog.showAndWait();
        if (courseToEdit.isPresent()) {
            int edited = courseMapper.update(courseToEdit.get());
            Notifications notifications;
            if (edited > 0) {
                notifications = showPrompt("修改课程信息成功",
                        String.format("课程 %s 的信息已经成功修改。", courseToEdit.get().getName()));
                notifications.showInformation();
            } else {
                notifications = showPrompt("修改课程信息失败",
                        String.format("课程 %s 的信息未能成功修改。", courseToEdit.get().getName()));
                notifications.showError();
            }
            reload();
        }
    }
}
